/**
 * \file character.hpp
 * \brief Curses++ character header file
 *
 * This file contains declarations for a %character class used to substitute for
 * the complex %curses system.
 *
 * \if LICENSE
 * Curses++ - Free C++ wrapper to the curses library.
 * Copyright (C) 2007 Sean Hunt
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
 * \endif
 */

#ifndef CURSESPLUSPLUS_STRING_HPP
#define CURSESPLUSPLUS_STRING_HPP

#include <cursesplusplus/locale.hpp>
#include <algorithm>
#include <functional>

namespace curses
{
	/// Curses string class.
	/**
	 *  This has the same interface as std::string, for the most part.
	 */
	template <typename Alloc = std::allocator<character> >
	class basic_string : public std::basic_string<character, std::char_traits<character>, Alloc>
	{
			/// Avoid namespace collisions
			typedef std::basic_string<character> base;
			typedef typename Alloc::size_type size_type;
		public:
			explicit basic_string (const Alloc& a = Alloc())
				: base (a)
			{}

			basic_string (const basic_string& str)
				: base(str)
			{}

			basic_string (const basic_string& str, size_type pos, size_type n = base::npos, const Alloc& a = Alloc())
				: base(str, pos, n, a)
			{}

			basic_string (const character* s, size_type n, const Alloc& a = Alloc())
				: base(s, n, a)
			{}

			basic_string (const character* s, const Alloc& a = Alloc())
				: base(s, a)
			{}

			basic_string (size_type n, character c, const Alloc& a = Alloc())
				: base(n, c, a)
			{}

			template <typename It>
			basic_string (It begin, It end, const Alloc& a = Alloc())
				: base(begin, end, a)
			{}

			basic_string (const char* c, const Alloc& a = Alloc())
			{
				const char * d = c;
				while (*d++);
				*this = basic_string(c, d, a);
			}

			basic_string (size_type n, char c, const Alloc& a = Alloc())
			{
				*this = basic_string(n, c);
			}

			basic_string (const char* c, size_type n, const Alloc& a = Alloc())
			{
				*this = basic_string(c, c+n, a);
			}

			using base::operator =;

			basic_string& operator = (const char * c)
			{
				return *this = basic_string(c);
			}

			basic_string& operator = (char c)
			{
				return *this = basic_string(1,c);
			}

			/// Set the foreground for every character in the string
			/**
			 *  Forwards to character::fg.
			 */
			basic_string& set_fg (character::color color)
			{
				std::for_each(this->begin(), this->end(), std::bind2nd(std::mem_fun(&character::set_fg), color));
				return *this;
			}

			/// Set the foreground for every character in the string
			/**
			 *  Forwards to character::set_bg.
			 */
			basic_string& set_bg (character::color color)
			{
				std::for_each(this->begin(), this->end(), std::bind2nd(std::mem_fun(&character::set_fg), color));
				return *this;
			}

			/// Set the attributes for every character in the string
			/**
			 *  Forwards to character::set_attr.
			 */
			basic_string& set_attr (character::attribute attr)
			{
				std::for_each(this->begin(), this->end(), std::bind2nd(std::mem_fun(&character::set_attr), attr));
				return *this;
			}

			/// Add certain attributes to all characters.
			/**
			 *  Forwards to character::add_attr.
			 */
			basic_string& add_attr (character::attribute attr)
			{
				std::for_each(this->begin(), this->end(), std::bind2nd(std::mem_fun(&character::add_attr), attr));
				return *this;
			}

			/// Remove certain attributes from all characters.
			/**
			 *  Forwards to character::remove_attr.
			 */
			basic_string& remove_attr (character::attribute attr)
			{
				std::for_each(this->begin(), this->end(), std::bind2nd(std::mem_fun(&character::remove_attr), attr));
				return *this;
			}

			/// Flip certain attributes on all characters.
			/**
			 *  Forwards to character::flip_attr.
			 */
			basic_string& flip_attr (character::attribute attr)
			{
				std::for_each(this->begin(), this->end(), std::bind2nd(std::mem_fun(&character::flip_attr), attr));
				return *this;
			}
	};

	typedef basic_string<> string;
}

#endif
